using System;
using System.Xml;
using System.Collections;

namespace Scenario.Modules.PCM.DataModel.ConfigurationManager.Entity
{
	//*********************************************************************
	//
	// XmlEntityAttributes Class
	//
	// The XmlEntityAttributes class represents a collection base of XmlEntityAttribute
	// Its imports methods from WAPI.XmlObjectSet like get set and add
	// XmlEntityAttributes Has no fields
	//
	//*********************************************************************
	public class XMLEntityAttributes : bOS.XML.Data.XMLObjectSet
	{
		public const string MAIN_NODE	= "Attributes";
		/** FIELDS **/

		/** no fields **/

		/** CONSTRUCTORS **/

		/** CONSTRUCTOR Empty **/
		public XMLEntityAttributes()
		{
			this.Init();
		}

		/** CONSTRUCTOR Width xml parsering**/
		public XMLEntityAttributes(System.Xml.XmlNode nodeList)
		{
			this.Parse (nodeList);
		}

		/** INSTANCE METHODS **/

		override public void Init()
		{
			this.RemoveAll();
		}

		/** Parsering method for filling the entities **/
		override public void Parse(System.Xml.XmlNode nodeList)
		{
			this.Init();
			
			System.Xml.XmlNode node;

			for ( int i=0; i<nodeList.ChildNodes.Count;i++)
			{
				node = nodeList.ChildNodes[i];

				switch ( node.Name) 
				{
					case XMLEntityAttribute.MAIN_NODE:
						this.Add ( new XMLEntityAttribute(node));
						break;
				}
			}

		}

		/** INSTANCE METHODS **/
		public bOS.XML.XMLNode GetShortXML()
		{
			bOS.XML.XMLNode xmlNode = new bOS.XML.XMLNode(XMLEntityAttributes.MAIN_NODE);
			XMLEntityAttribute xmlEntityAttribute = null;
			for ( int i=0; i<this.Count;i++)
			{
				xmlEntityAttribute = (XMLEntityAttribute)this[i];
				xmlNode.AddNode ( xmlEntityAttribute.GetShortXML() );
			}

			return xmlNode;
		}

		override public bOS.XML.XMLNode GetXMLNode()
		{
			bOS.XML.XMLNode xmlNode = new bOS.XML.XMLNode(XMLEntityAttributes.MAIN_NODE);

			for ( int i=0; i<this.Count;i++)
			{
				xmlNode.AddNode ( this[i].GetXMLNode() );
			}

			return xmlNode;
		}


		/** Method for return an EntityAttribute from collection **/
		public XMLEntityAttribute Get(string sName)
		{
			XMLEntityAttribute attribute;

			for ( int i=0; i<this.List.Count; i++)
			{
				attribute = (XMLEntityAttribute)this.List[i];
				if ( attribute.Name == sName )
				{
					return attribute;
				}
			}

			throw new Exception.EntityAttributeNotFound(sName + " not found.");
		}

		/** Method for checking an EntityAttribute in collection **/
		public bool AlmostIn(XMLEntityAttributes vValues)
		{
			XMLEntityAttribute leftAttribute;
			XMLEntityAttribute rightAttribute;

			for ( int i=0; i<this.List.Count; i++)
			{
				leftAttribute = (XMLEntityAttribute)this.List[i];

				try
				{
					rightAttribute = vValues.Get(leftAttribute.Name);
				}
				catch ( Exception.EntityAttributeNotFound)
				{
					return false;
				}
			}
			
			return true;
		}

		/** Method for checking an entity in collection **/
		public bool AlmostInByName (string sName)
		{
			XMLEntityAttribute EntityAttribute;

			for ( int i=0; i<this.List.Count; i++)
			{
				EntityAttribute = (XMLEntityAttribute)this.List[i];

				if (EntityAttribute.Name == sName)
				{
					return true;
				}
			}
			
			return false;
		}

		/** method to remove an attribute from collectio by its name**/
		public bool RemoveByName(string sName)
		{
			XMLEntityAttribute EntityAttribute;

			for ( int i=0; i<this.List.Count; i++)
			{
				EntityAttribute = (XMLEntityAttribute)this.List[i];

				if (EntityAttribute.Name == sName)
				{
					this.List.Remove(EntityAttribute);
					return true;
				}
			}
			
			return false;
		}

		/** SORTING  FIELDS **/

		public enum SortFields 
		{
			Name,
			EntityType,
			EntityRef,
			Order,
			ObjectData
		}

		/** SORTING METHODS **/


		public void Sort(SortFields sortField, bool isAscending) 
		{
			switch (sortField) 
			{
				case SortFields.Name:
					InnerList.Sort(new NameComparer());
					break;
				case SortFields.EntityType:
					InnerList.Sort(new EntityTypeComparer());
					break;
				case SortFields.EntityRef:
					InnerList.Sort(new EntityRefComparer());
					break;
				case SortFields.Order:
					InnerList.Sort(new OrderComparer());
					break;
				case SortFields.ObjectData:
					InnerList.Sort(new ObjectDataComparer());
					break;
				
			}
			if (!isAscending) InnerList.Reverse();
		}


		private sealed class NameComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLEntityAttribute first = (XMLEntityAttribute) x;
				XMLEntityAttribute second = (XMLEntityAttribute) y;
				return first.Name.CompareTo(second.Name);
			}
		}

		private sealed class EntityTypeComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLEntityAttribute first = (XMLEntityAttribute) x;
				XMLEntityAttribute second = (XMLEntityAttribute) y;
				return first.EntityType.CompareTo(second.EntityType);
			}
		}

		private sealed class EntityRefComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLEntityAttribute first = (XMLEntityAttribute) x;
				XMLEntityAttribute second = (XMLEntityAttribute) y;
				return first.EntityRef.CompareTo(second.EntityRef);
			}
		}

		private sealed class OrderComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLEntityAttribute first = (XMLEntityAttribute) x;
				XMLEntityAttribute second = (XMLEntityAttribute) y;
				return first.Order.CompareTo(second.Order);
			}
		}

		private sealed class ObjectDataComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLEntityAttribute first = (XMLEntityAttribute) x;
				XMLEntityAttribute second = (XMLEntityAttribute) y;
				return first.ObjectData.CompareTo(second.ObjectData);
			}
		}

		/** WAPI Wrappers to call SCENARIO ENGINE **/

		/** no wapi **/
	}
}